package com.example.my_bookkeeping;


import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;

import static java.lang.Thread.sleep;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import com.example.my_bookkeeping.data.manager.UserManager;
import com.example.my_bookkeeping.data.user.User;
import com.example.my_bookkeeping.ui.account.AccountFragment;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class EditUserTest {

    @Rule
    public ActivityScenarioRule<MainActivity> mActivityScenarioRule =
            new ActivityScenarioRule<>(MainActivity.class);

    private UserManager userDataStore;

    @Before
    public void setup(){
        userDataStore = UserManager.getInstance();
        userDataStore.reset();
    }

    @After
    public void teardown(){
        userDataStore.reset();
    }

    @Test
    public void editUserTest() throws InterruptedException {
        ViewInteraction bottomNavigationItemView = onView(
                allOf(withId(R.id.item_account), withContentDescription("我的账户"),
                        childAtPosition(
                                childAtPosition(
                                        withId(R.id.bottom_navigation_view),
                                        0),
                                4),
                        isDisplayed()));
        bottomNavigationItemView.perform(click());

        sleep(100);
        ViewInteraction appCompatButton = onView(
                allOf(withId(R.id.btn_edit_account), withText("编辑账户"),
                        childAtPosition(
                                childAtPosition(
                                        withId(R.id.modifyUserCard),
                                        0),
                                1),
                        isDisplayed()));
        appCompatButton.perform(click());

        ViewInteraction appCompatEditText = onView(
                allOf(withId(R.id.et_username),
                        childAtPosition(
                                childAtPosition(
                                        withId(android.R.id.custom),
                                        0),
                                0),
                        isDisplayed()));
        appCompatEditText.perform(replaceText("李四"), closeSoftKeyboard());

        ViewInteraction appCompatEditText2 = onView(
                allOf(withId(R.id.et_user_type),
                        childAtPosition(
                                childAtPosition(
                                        withId(android.R.id.custom),
                                        0),
                                1),
                        isDisplayed()));
        appCompatEditText2.perform(replaceText("微信余额"), closeSoftKeyboard());

        ViewInteraction appCompatEditText3 = onView(
                allOf(withId(R.id.et_user_balance),
                        childAtPosition(
                                childAtPosition(
                                        withId(android.R.id.custom),
                                        0),
                                2),
                        isDisplayed()));
        appCompatEditText3.perform(replaceText("1000"), closeSoftKeyboard());

        ViewInteraction appCompatButton2 = onView(
                allOf(withId(android.R.id.button1), withText("确定"),
                        childAtPosition(
                                childAtPosition(
                                        withClassName(is("android.widget.ScrollView")),
                                        0),
                                3)));
        appCompatButton2.perform(scrollTo(), click());

        // 断言数据库中当前的账户信息已更新
        User user = userDataStore.getCurrentUser();
        assert user != null;
        assert user.getName().equals("李四");
        assert user.getRemark().equals("微信余额");
        assert user.getAmount() == 1000;

        // 断言当前视图的内容已更新
        mActivityScenarioRule.getScenario().onActivity(activity -> {
            AccountFragment fragment = (AccountFragment) activity.getSupportFragmentManager()
                    .findFragmentByTag("f" + 3);
            assert fragment != null;
            View rootView = fragment.getView();
            assert rootView!= null;
            Spinner spinnerAccount = rootView.findViewById(R.id.spinner_account);
            TextView tvAccountName = rootView.findViewById(R.id.tv_account_name);
            TextView tvAccountCategory = rootView.findViewById(R.id.tv_account_category);
            TextView tvAccountBalance = rootView.findViewById(R.id.tv_account_balance);
            assert tvAccountName.getText().toString().equals("李四");
            assert tvAccountCategory.getText().toString().equals("微信余额");
            assert tvAccountBalance.getText().toString().equals("1000.0");
            String selectedItem = ((User)spinnerAccount.getSelectedItem()).getName();
            assert selectedItem.equals("李四");
        });
    }

    private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }
}
